import requests
import xmltodict
from wechatpy.fields import StringField
from wechatpy.messages import MESSAGE_TYPES, UnknownMessage
from wechatpy.events import EVENT_TYPES, BaseEvent
from wechatpy.utils import to_text
from core.config import settings
from core.logger import log
from services.redis_service import AsyncRedisService


class EventMessage(BaseEvent):
    """事件消息"""
    event = "kf_msg_or_event"
    token = StringField("Token")
    OpenKfId = StringField("OpenKfId")

async def get_event_msg(msg:EventMessage,server:AsyncRedisService,limit: int=1000, voice_format: int=0)->list:
    token = msg.token
    OpenKfId = msg.OpenKfId
    cursor = await server.get_qw_sync_msg_cursor()
    ACCESS_TOKEN = await server.get_qw_access_token()
    if ACCESS_TOKEN is None:
        ACCESS_TOKEN = await get_qw_access_token()
        await server.set_qw_access_token(ACCESS_TOKEN)
    url = f"https://qyapi.weixin.qq.com/cgi-bin/kf/sync_msg?access_token={ACCESS_TOKEN}"
    data = {
        "cursor": cursor,
        "token": token,
        "limit": limit,
        "voice_format": voice_format,
        "open_kfid": OpenKfId
    }
    resp = requests.post(url,json=data).json()
    log.info(f"获取access_token消息结果：{resp}")
    if resp.get("errcode") == 0:
        """
        存储这次获取的游标
        """
        cursor = resp.get("next_cursor")
        await server.set_qw_sync_msg_cursor(cursor)
        return resp.get("msg_list")
    raise ValueError(f"获取消息失败，错误码：{resp.get('errcode')}，错误信息：{resp.get('errmsg')}")
async def get_qw_access_token():
    url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
    corpid= settings.QW_APP_ID
    corpsecret = settings.QW_KF_SECRET
    resp = requests.get(url,params={"corpid":corpid,"corpsecret":corpsecret}).json()
    if resp.get("errcode") == 0:
        return resp.get("access_token")
    raise ValueError(f"获取 access_token 失败，错误码：{resp.get('errcode')}，错误信息：{resp.get('errmsg')}")
async def get_all_kf_id_list(access_token):
    url = f"https://qyapi.weixin.qq.com/cgi-bin/kf/account/list?access_token={access_token}"
    data = {
        "offset": 0,
        "limit": 10
    }
    resp = requests.post(url,json=data).json()
    if resp.get("errcode") == 0:
        return resp.get("account_list")
    raise ValueError(f"获取客服列表失败，错误码：{resp.get('errcode')}，错误信息：{resp.get('errmsg')}")

async def get_kf_link(access_token,phone,open_kfid):
    url = f"https://qyapi.weixin.qq.com/cgi-bin/kf/add_contact_way?access_token={access_token}"
    data = {
        "open_kfid": open_kfid,
        "scene": phone
    }
    resp = requests.post(url,json=data).json()
    if resp.get("errcode") == 0:
        # log.info(f"获取客服链接成功{resp}")
        return resp.get("url")
    raise ValueError(f"获取客服链接失败，错误码：{resp.get('errcode')}，错误信息：{resp.get('errmsg')}")
def parse_message_local(xml):
    """
    解析微信服务器推送的 XML 消息

    :param xml: XML 消息
    :return: 解析成功返回对应的消息或事件，否则返回 ``UnknownMessage``
    """
    if not xml:
        return
    message = xmltodict.parse(to_text(xml))["xml"]
    message_type = message["MsgType"].lower()
    event_type = None
    if message_type == "event" or message_type.startswith("device_"):
        if "Event" in message:
            event_type = message["Event"].lower()
        # special event type for device_event
        if event_type is None and message_type.startswith("device_"):
            event_type = message_type
        elif message_type.startswith("device_"):
            event_type = f"device_{event_type}"

        if event_type == "subscribe" and message.get("EventKey"):
            event_key = message["EventKey"]
            if event_key.startswith(("scanbarcode|", "scanimage|")):
                event_type = "subscribe_scan_product"
                message["Event"] = event_type
            elif event_key.startswith("qrscene_"):
                # Scan to subscribe with scene id event
                event_type = "subscribe_scan"
                message["Event"] = event_type
                message["EventKey"] = event_key[len("qrscene_") :]
        # if event_type == "kf_msg_or_event":
        #     message_class = EventMessage
        message_class = EVENT_TYPES.get(event_type, UnknownMessage)
    else:
        message_class = MESSAGE_TYPES.get(message_type, UnknownMessage)
    return message_class(message)